# -*- coding:utf-8 -*-
import os
import sys

import pandas as pd
import numpy as np
from scipy.spatial import KDTree
from PyQt5.QtWidgets import (
    QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
    QPushButton, QLabel, QFileDialog, QMessageBox,
    QTableWidget, QTableWidgetItem, QHeaderView, QSplitter,
    QSizePolicy, QProgressDialog, QApplication, QLineEdit
)
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QPainter, QPen, QColor
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from data_processor import ProcessData
from config import AppConfig

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

class MplCanvas(FigureCanvas):
    """Matplotlib画布"""
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.config = AppConfig()
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        super().__init__(self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, 
                                   QSizePolicy.Expanding, 
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

class CompareUI(QMainWindow):
    """测量点与检查线比较界面"""
    def __init__(self):
        super().__init__()
    
        self.coincident_points = None  # 存储重合点数据
        # 初始化必要的变量
        self.config = AppConfig()
        self.processor = ProcessData()
        # 将processor的config设置为当前UI的config
        self.processor.config = self.config
        self.init_ui()
    
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle('皖江绘2.0-单波束检查模块')
        self.resize(1400, 1000)
        
        # 中心部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        
        # 按钮区域布局
        button_layout = QHBoxLayout()
        
        # 导入按钮
        self.import_a_btn = QPushButton('导入测量点')
        self.import_a_btn.clicked.connect(self.import_data_a)
        self.import_b_btn = QPushButton('导入检查点')
        self.import_b_btn.clicked.connect(self.import_data_b)
        self.compare_btn = QPushButton('计算重合点高程较差')
        self.compare_btn.clicked.connect(self.calculate_coincident_points)
        self.compare_btn.setEnabled(False)
        
        # 距离阈值输入
        self.threshold_label = QLabel('距离阈值(米):')
        self.threshold_input = QLineEdit('0.3')
        self.threshold_input.setFixedWidth(80)
        self.threshold_input.textChanged.connect(self._check_enable_compare)
        
        # 高程限差输入
        self.tolerance_label = QLabel('高程限差(米):')
        self.tolerance_input = QLineEdit('0.3')
        self.tolerance_input.setFixedWidth(80)
        
        # 导出按钮
        self.export_btn = QPushButton('导出Excel')
        self.export_btn.clicked.connect(self.export_to_excel)
        self.export_btn.setEnabled(False)
        
        # 添加到按钮布局
        button_layout.addWidget(self.import_a_btn)
        button_layout.addWidget(self.import_b_btn)
        button_layout.addWidget(self.threshold_label)
        button_layout.addWidget(self.threshold_input)
        button_layout.addWidget(self.tolerance_label)
        button_layout.addWidget(self.tolerance_input)
        button_layout.addWidget(self.compare_btn)
        button_layout.addWidget(self.export_btn)
        button_layout.addStretch()
        
        # 状态栏
        self.status_label = QLabel('等待导入数据...')
        
        # 距离信息显示区域
        distance_layout = QHBoxLayout()
        self.measurement_distance_label = QLabel('测量点总距离: 0.000米')
        self.check_distance_label = QLabel('检查点总距离: 0.000米')
        self.ratio_label = QLabel('检查点距离占比: 0.00% (需达到5%标准)')
        self.ratio_label.setStyleSheet('color: red;')
        
        distance_layout.addWidget(self.measurement_distance_label)
        distance_layout.addWidget(self.check_distance_label)
        distance_layout.addWidget(self.ratio_label)
        distance_layout.addStretch()
        
        # 创建分割器
        splitter = QSplitter(Qt.Vertical)
        
        # 创建表格显示区域
        self.table_widget = QTableWidget()
        self.table_widget.setColumnCount(8)
        self.table_widget.setHorizontalHeaderLabels(['测量点N', '测量点E', '测量点高程', '检查点N', '检查点E', '检查点高程', '高程较差（米）', '距离（米）'])
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        
        # 创建图形显示区域
        self.canvas_widget = MplCanvas(self, width=5, height=4, dpi=100)
        
        # 添加到分割器
        splitter.addWidget(self.table_widget)
        splitter.addWidget(self.canvas_widget)
        
        # 设置初始大小比例
        splitter.setSizes([300, 500])
        
        # 添加到主布局
        main_layout.addLayout(button_layout)
        main_layout.addWidget(self.status_label)
        main_layout.addLayout(distance_layout)
        main_layout.addWidget(splitter)
    
    def _calculate_total_distance(self, points):
        """计算所有点形成的路径总距离
        优化版：使用NumPy进行向量化计算，提高效率
        """
        if len(points) < 2:
            return 0.0
        
        # 将points列表转换为NumPy数组
        points_array = np.array(points)
        
        # 提取x,y坐标列
        x_coords = points_array[:, 0]
        y_coords = points_array[:, 1]
        
        # 计算相邻点之间的距离平方差
        dx = x_coords[1:] - x_coords[:-1]
        dy = y_coords[1:] - y_coords[:-1]
        
        # 计算距离并求和
        distances = np.sqrt(dx**2 + dy**2)
        total_distance = np.sum(distances)
        
        return total_distance
        
    def _update_distance_info(self):
        """更新距离信息显示"""
        # 更新测量点总距离
        self.measurement_distance_label.setText(f"测量点总距离: {self.config.measurement_distance:.3f}米")
        # 更新检查点总距离
        self.check_distance_label.setText(f"检查点总距离: {self.config.check_distance:.3f}米")
        
        # 计算并更新检查点距离占比
        if self.config.measurement_distance > 0:
            self.config.check_ratio = (self.config.check_distance / self.config.measurement_distance) * 100
            # 根据是否达到5%标准设置文字颜色
            if self.config.check_ratio >= 5:
                self.ratio_label.setStyleSheet('color: green;')
                self.ratio_label.setText(f"检查点距离占比: {self.config.check_ratio:.2f}% (已达到5%标准)")
            else:
                self.ratio_label.setStyleSheet('color: red;')
                self.ratio_label.setText(f"检查点距离占比: {self.config.check_ratio:.2f}% (需达到5%标准)")
        else:
            self.ratio_label.setStyleSheet('color: red;')
            self.ratio_label.setText(f"检查点距离占比: 0.00% (需达到5%标准)")
        
    def import_data_a(self):
        try:
            # 选择文件
            file_in, _ = QFileDialog.getOpenFileName(
                self, 
                "选择数据文件", 
                "", 
                "LOG文件 (*.LOG);;asc文件 (*.asc));;文本文件 (*.txt)"
            )
            
            if not file_in:
                return
            # 根据文件类型选择处理方式
            if file_in.lower().endswith('.log'):
                # print(f"开始导入文件: {file_in}")
                self.status_label.setText(f"正在导入文件: {file_in}")
                
                # 初始化数据
                filepath, tempfilename = os.path.split(file_in)
                filepath = filepath.replace('/', '\\')
                
                self.config.notesection = []
                self.config.notemenu = []
                try:
                    # 读取文件
                    with open(file_in, 'r') as f:
                        for line in f:
                            line = line.strip('\n')
                            
                            # 定位文件名中的位置信息，作为日志文件名的一部分
                            e = line.rfind('\\')
                            fi = line[e+1:] if e != -1 else line
                            
                            # 与原代码完全一致的路径拼接方式
                            full_path = filepath + '\\' + fi
                            
                            # 检查文件是否存在
                            if not os.path.exists(full_path):
                                print(f"文件不存在: {full_path}")
                                continue
                                
                            self.config.notesection.append(fi)
                            self.config.notemenu.append(full_path)
                except Exception as e:
                    print(f"处理文件 {filepath} 时发生错误: {str(e)}")
                    QMessageBox.critical(self, "错误", f"处理文件 {filepath} 时发生错误: {str(e)}")
                    self.status_label.setText("等待导入数据...")
                    return
                
                # 添加调试信息
                # print(f"找到 {len(self.config.notesection)} 个断面")
                
                total_sections = len(self.config.notesection)
                
                if total_sections == 0:
                    QMessageBox.warning(self, "警告", "没有找到有效的断面文件")
                    self.status_label.setText("等待导入数据...")
                    return
                    
                # 创建进度对话框
                progress = QProgressDialog("正在处理断面数据...", "取消", 0, total_sections, self)
                progress.setWindowTitle("处理中")
                progress.setWindowModality(Qt.WindowModal)
                progress.setValue(0)
                progress.setMinimumDuration(0)  # 确保进度条总是显示
                progress.show()  # 显示进度条
                
                # 初始化存储所有A点数据的列表
                all_a_points = []
                
                # 初始化测量点总距离
                total_distance = 0.0
                
                # 批量处理每个断面
                for i in range(total_sections):
                    # 检查用户是否取消
                    if progress.wasCanceled():
                        self.status_label.setText("操作已取消")
                        return
                        
                    # 确保列表长度足够
                    if i not in self.config.EC1:
                        self.config.EC1[i] = []
                    if i not in self.config.POS:
                        self.config.POS[i] = []
                        
                    self.config.dmnum = i
                    try:
                        # 1. 清空当前断面的数据结构
                        self.config.EC1[i] = []
                        self.config.POS[i] = []
                        
                        # 2. 使用_read_and_parse_file函数读取和解析文件
                        file_path = self.config.notemenu[i]
                        self.processor._read_and_parse_file(file_path)
                        # print(f"成功读取并解析断面{i}数据")
                        
                        # 3. 使用_merge_ec1_and_pos_data函数合并EC1和POS数据
                        merged_data = self.processor._merge_ec1_and_pos_data()
                        # 存储合并数据到配置中
                        if i not in self.config.merged_data:
                            self.config.merged_data[i] = []
                        self.config.merged_data[i] = merged_data  #时间 E N 水深
                        # print(f"成功合并断面{i}的EC1和POS数据，合并了{len(merged_data)}个点")
                        
                        # 4. 将合并的数据添加到总数据中
                        section_points = []
                        for point in merged_data:
                            point_data = [point[1], point[2], point[3]] #E N 水深
                            all_a_points.append(point_data)
                            section_points.append(point_data)
                        
                        # 5. 计算当前断面的距离并累加到总距离中
                        section_distance = self._calculate_total_distance(section_points)
                        total_distance += section_distance
                        
                        # 更新进度条
                        progress.setValue(i + 1)
                        QApplication.processEvents()  # 确保界面及时更新
                        
                    except Exception as e:
                        print(f"处理断面{i}时发生错误: {str(e)}")
                        
                
                # 将所有数据转换为numpy数组
                if len(all_a_points) > 0:
                    self.config.ys_piont = np.array(all_a_points)
                    
                    # 设置测量点总距离（已在循环中累加计算）
                    self.config.measurement_distance = total_distance
                    
                    # 更新界面显示
                    self.status_label.setText(f"已导入测量点，共{len(self.config.ys_piont)}个点")
                    QMessageBox.information(self, "成功", f"测量点导入成功，共{len(self.config.ys_piont)}个点\n总距离: {self.config.measurement_distance:.3f}米")
                    self._check_enable_compare()
                    self._update_distance_info()
                    
                    # 导入测量点后立即绘制
                    if hasattr(self, '_plot_results'):
                        self._plot_results()
                else:
                    self.status_label.setText("等待导入数据...")
                    QMessageBox.warning(self, "警告", "导入的文件中没有找到有效的测量点数据")
        
            if file_in.lower().endswith(('.asc', '.txt')):
                try:
                    # 使用numpy高效读取规则数据
                    point_cloud = np.loadtxt(file_in, delimiter=',', usecols=(0,1,2))
                    
                    # 验证数据维度
                    if point_cloud.shape[1] != 3:
                        raise ValueError("文件格式错误，需要3列数据（E, N, 水深）")

                    # 转换为列表格式保持数据结构统一
                    all_a_points = point_cloud.tolist()

                    # 更新配置
                    self.config.ys_piont = np.array(all_a_points)
    

                    # 跳过进度条直接更新UI
                    self.status_label.setText(f"已导入规则点云，共{len(all_a_points)}个点")
                    QMessageBox.information(self, "成功", f"规则点云导入成功")
                    self._check_enable_compare()
                    self._update_distance_info()

                     # 导入检查点后立即绘制
                    if hasattr(self, '_plot_results'):
                        self._plot_results()

                except Exception as e:
                    print(f"处理点云文件出错: {str(e)}")
                    QMessageBox.critical(self, "错误", f"点云文件处理失败: {str(e)}")
                    return

        
        except Exception as e:
            print(f"导入测量点时发生错误: {str(e)}")
            QMessageBox.critical(self, "错误", f"导入测量点时发生错误: {str(e)}")
            self.status_label.setText("等待导入数据...")
        
    def import_data_b(self):
        """导入检查线B数据"""
        try:
            # 选择RAW文件，支持多选
            file_paths, _ = QFileDialog.getOpenFileNames(
                self, 
                "选择RAW数据文件", 
                "", 
                "RAW文件 (*.RAW);;asc文件 (*.asc));;文本文件 (*.txt)"
            )
            
            if not file_paths:
                return
            # 初始化存储所有B点数据的列表
            all_b_points = []
            
            # 初始化检查点总距离
            total_check_distance = 0.0
            # 根据文件类型选择处理方式
            for i, file_path in enumerate(file_paths):
                if file_path.lower().endswith(('.asc', '.txt')): 
                    try:
                        # 使用numpy高效读取规则数据
                        point_cloud = np.loadtxt(file_path, delimiter=',', usecols=(0,1,2))
                        
                        # 验证数据维度
                        if point_cloud.shape[1] != 3:
                            raise ValueError("文件格式错误，需要3列数据（E, N, 水深）")

                        # 转换为列表格式保持数据结构统一
                        all_b_points = point_cloud.tolist()

                        # 更新配置
                        self.config.check_point = np.array(all_b_points)
        

                        # 跳过进度条直接更新UI
                        self.status_label.setText(f"已导入规则点云，共{len(all_b_points)}个点")
                        QMessageBox.information(self, "成功", f"规则点云导入成功")
                        self._check_enable_compare()
                        self._update_distance_info()

                        # 导入检查点后立即绘制
                        if hasattr(self, '_plot_results'):
                            self._plot_results()

                    except Exception as e:
                        print(f"处理点云文件出错: {str(e)}")
                        QMessageBox.critical(self, "错误", f"点云文件处理失败: {str(e)}")
                        return

                if file_path.lower().endswith('.raw'):   # 否则，检查点云文件     
                    # 更新状态标签
                    self.status_label.setText(f"正在导入{len(file_paths)}个RAW文件...")
                    try:
                        # 读取和解析RAW文件
                        filename = os.path.basename(file_path)
                        
                        # 设置当前文件的dmnum并清空相关数据结构
                        self.config.dmnum = i
                        if i not in self.config.EC1:
                            self.config.EC1[i] = []
                        if i not in self.config.POS:
                            self.config.POS[i] = []
                        
                        # 清空当前文件的数据
                        self.config.EC1[i] = []
                        self.config.POS[i] = []
                        
                        # 读取和解析文件
                        self.processor._read_and_parse_file(file_path)
                        # print(f"成功读取并解析文件: {filename}")
                        
                        # 合并数据
                        merged_data = self.processor._merge_ec1_and_pos_data()
                        # print(f"成功合并{filename}的数据，共{len(merged_data)}个点")
                        
                        # 将合并的数据添加到总数据中
                        file_points = []
                        for point in merged_data:
                            point_data = [point[1], point[2], point[3]]
                            all_b_points.append(point_data)
                            file_points.append(point_data)
                        
                        # 计算当前文件的距离并累加到总距离中
                        file_distance = self._calculate_total_distance(file_points)
                        total_check_distance += file_distance
                        
                    except Exception as e:
                        print(f"处理文件{filename}时发生错误: {str(e)}")
                        # 继续处理下一个文件，不中断整个导入过程
                        QMessageBox.warning(self, "警告", f"处理文件{filename}时发生错误: {str(e)}")
                
                    # 将所有数据转换为numpy数组
                    if len(all_b_points) > 0:
                        self.config.check_point = np.array(all_b_points)
                        
                        # 设置检查点总距离（已在循环中累加计算）
                        self.config.check_distance = total_check_distance
                        
                        # 更新界面显示
                        self.status_label.setText(f"已导入检查点，共{len(self.config.check_point)}个点")
                        QMessageBox.information(self, "成功", f"检查点导入成功，共{len(self.config.check_point)}个点\n总距离: {self.config.check_distance:.3f}米")
                        self._check_enable_compare()
                        self._update_distance_info()
                        
                        # 导入检查点后立即绘制
                        if hasattr(self, '_plot_results'):
                            self._plot_results()
                    else:
                        self.status_label.setText("等待导入数据...")
                        QMessageBox.warning(self, "警告", "导入的文件中没有找到有效的测量点数据")
            

        except Exception as e:
            print(f"导入检查点时发生错误: {str(e)}")
            QMessageBox.critical(self, "错误", f"导入检查点时发生错误: {str(e)}")
            self.status_label.setText("等待导入数据...")
    
   
    
    def _check_enable_compare(self):
        """检查是否可以启用比较按钮"""
        # 检查数据是否已导入
        if self.config.ys_piont is None or self.config.check_point is None:
            self.compare_btn.setEnabled(False)
            return
        
        # 检查阈值输入是否为有效数值
        try:
            threshold = float(self.threshold_input.text())
            if threshold <= 0:
                raise ValueError("阈值必须大于0")
            # 数据已导入且阈值有效，可以启用比较按钮
            self.compare_btn.setEnabled(True)
            self.status_label.setText(f"已导入测量点({len(self.config.ys_piont)}点)和检查点({len(self.config.check_point)}点)，可以开始比较")
        except ValueError:
            # 阈值输入无效，禁用比较按钮
            self.compare_btn.setEnabled(False)
            self.status_label.setText("请输入有效的距离阈值")
    
    def calculate_coincident_points(self):
        """计算重合点和高程较差 - 使用KDTree优化，确保一对一匹配"""
        if self.config.ys_piont is None or self.config.check_point is None:
            QMessageBox.warning(self, "警告", "请先导入测量点和检查点的数据")
            return
        
        try:
            # print("===== 开始重合点计算 =====")
            # print(f"测量点数量: {len(self.data_a)}, 检查点数量: {len(self.config.check_point)}")
            
            # 从UI获取距离阈值
            try:
                threshold = float(self.threshold_input.text())
                # print(f"输入的距离阈值: {threshold}")
                if threshold <= 0:
                    raise ValueError("阈值必须大于0")
            except ValueError as e:
                # print(f"无效的距离阈值: {str(e)}")
                QMessageBox.warning(self, "警告", f"请输入有效的距离阈值: {str(e)}")
                return
            # print(f"使用的距离阈值: {threshold}米")
            
            # 提取测量点的XY坐标构建KDTree（反向匹配）
            a_points_xy = self.config.ys_piont[:, :2]  # 测量点的XY坐标
            # print(f"测量点XY坐标形状: {a_points_xy.shape}")
            
            # 构建测量点的KDTree
            from scipy.spatial import KDTree
            kdtree_a = KDTree(a_points_xy)
            # print("测量点KDTree构建完成")
            
            # 存储重合点信息
            coincident_list = []
            
            # 用于记录已经匹配的测量点索引，避免重复匹配
            matched_a_indices = set()
            
            # print("开始查找重合点...")
            
            # 遍历每个检查点，查找最近的测量点
            for i in range(len(self.config.check_point)):
                # 提取检查点的坐标
                b_point = self.config.check_point[i]
                b_x, b_y, b_z = b_point[0], b_point[1], b_point[2]
                
                # 使用KDTree查询最近的测量点
                distance, idx = kdtree_a.query([b_x, b_y])
                
                # 如果距离小于阈值且该测量点未被匹配，则认为是重合点
                if distance <= threshold and idx not in matched_a_indices:
                    # 提取测量点的坐标
                    a_point = self.config.ys_piont[idx]
                    a_x, a_y, a_z = a_point[0], a_point[1], a_point[2]
                    
                    # 计算高程较差
                    elevation_diff = a_z - b_z
                    # 存储测量点XY、高程和检查点XY、高程，以及高程较差和距离
                    coincident_list.append([a_x, a_y, a_z, b_x, b_y, b_z, elevation_diff, distance])
                    
                    # 标记该测量点已被匹配
                    matched_a_indices.add(idx)
            
            # 转换为numpy数组
            self.coincident_points = np.array(coincident_list) if coincident_list else np.array([])
            
            # 输出结果
            # print(f"找到的重合点数量: {len(self.coincident_points)}")
            # print(f"理论上最大重合点数量: {len(self.config.check_point)}")
            
            # 显示结果
            if hasattr(self, '_display_results'):
                self._display_results()
                self._check_enable_export()
            if hasattr(self, '_plot_results'):
                self._plot_results()
            
            # 更新状态栏
            self.status_label.setText(f"找到{len(self.coincident_points)}个重合点")
            QMessageBox.information(self, "成功", f"计算完成，找到{len(self.coincident_points)}个重合点")
            
        except Exception as e:
            print(f"计算重合点失败: {str(e)}")
            import traceback
            traceback.print_exc()
            QMessageBox.critical(self, "错误", f"计算重合点失败：{str(e)}")

    def _check_enable_export(self):
        """检查是否可以启用导出按钮"""
        self.export_btn.setEnabled(self.coincident_points is not None and len(self.coincident_points) > 0)
        
    def export_to_excel(self):
        """将满足限差要求的数据导出到Excel表格"""
        if self.coincident_points is None or len(self.coincident_points) == 0:
            QMessageBox.warning(self, "警告", "没有可导出的数据")
            return
        
        try:
            # 获取当前高程限差值
            try:
                tolerance = float(self.tolerance_input.text())
                if tolerance < 0:
                    raise ValueError("限差值必须大于等于0")
            except ValueError:
                # 如果输入无效，使用默认值0.5
                tolerance = 0.5
                QMessageBox.information(self, "提示", "使用默认高程限差值: 0.5米")
            
            # 过滤出满足限差要求的数据点
            filtered_points = []
            for point in self.coincident_points:
                a_x, a_y, a_z, b_x, b_y, b_z, diff, dist = point
                if abs(diff) <= tolerance:
                    filtered_points.append([a_x, a_y, a_z, b_x, b_y, b_z, diff, dist])
            
            if not filtered_points:
                QMessageBox.warning(self, "警告", f"没有满足高程限差({tolerance}米)要求的数据点")
                return
            
            # 让用户选择保存位置
            file_path, _ = QFileDialog.getSaveFileName(
                self, "保存Excel文件", "", "Excel Files (*.xlsx)"
            )
            
            if not file_path:
                return
            
            # 创建DataFrame并导出到Excel
            import pandas as pd
            
            # 表头
            columns = [
                '测量点N', '测量点E', '测量点高程',
                '检查点N', '检查点E', '检查点高程',
                '高程较差（米）', '距离（米）'
            ]
            
            # 创建DataFrame
            df = pd.DataFrame(filtered_points, columns=columns)
            
            # 设置距离列显示三位小数
            df['距离（米）'] = df['距离（米）'].apply(lambda x: f"{float(x):.3f}")
            
            # 导出到Excel
            with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
                df.to_excel(writer, index=False, sheet_name='满足限差要求的重合点')
            
            QMessageBox.information(self, "成功", f"数据已成功导出到:\n{file_path}")
            
        except Exception as e:
            print(f"导出Excel失败: {str(e)}")
            import traceback
            traceback.print_exc()
            QMessageBox.critical(self, "错误", f"导出Excel失败：{str(e)}")
    
    def _display_results(self):
        """在表格中显示结果"""
        if self.coincident_points is None or len(self.coincident_points) == 0:
            self.table_widget.setRowCount(0)
            return
        
        # 设置表格行数
        self.table_widget.setRowCount(len(self.coincident_points))
        
        # 填充表格数据
        for i, point in enumerate(self.coincident_points):
            a_x, a_y, a_z, b_x, b_y, b_z, diff, dist = point
            
            # 设置表格项
            self.table_widget.setItem(i, 0, QTableWidgetItem(f"{a_x:.3f}"))  # 测量点X
            self.table_widget.setItem(i, 1, QTableWidgetItem(f"{a_y:.3f}"))  # 测量点Y
            self.table_widget.setItem(i, 2, QTableWidgetItem(f"{a_z:.3f}"))  # 测量点高程
            self.table_widget.setItem(i, 3, QTableWidgetItem(f"{b_x:.3f}"))  # 检查点X
            self.table_widget.setItem(i, 4, QTableWidgetItem(f"{b_y:.3f}"))  # 检查点Y
            self.table_widget.setItem(i, 5, QTableWidgetItem(f"{b_z:.3f}"))  # 检查点高程
            self.table_widget.setItem(i, 6, QTableWidgetItem(f"{diff:.3f}"))  # 高程较差
            self.table_widget.setItem(i, 7, QTableWidgetItem(f"{dist:.3f}"))  # 距离
            
            # 设置高程较差单元格的颜色
            item = self.table_widget.item(i, 6)
            # 尝试从UI获取高程限差值
            try:
                tolerance = float(self.tolerance_input.text())
                if tolerance < 0:
                    raise ValueError("限差值必须大于等于0")
            except ValueError:
                # 如果输入无效，使用默认值0.5
                tolerance = 0.5
            
            # 根据差值与限差的比较设置颜色
            if abs(diff) > tolerance:
                item.setBackground(QColor(255, 200, 200))  # 不满足要求时显示红色
            else:
                item.setBackground(QColor(200, 255, 200))  # 满足要求时显示绿色
    
    def _plot_results(self):
       
        """绘制结果图形"""
        self.canvas_widget.axes.clear()
        
        # 绘制所有点
        if self.config.ys_piont is not None:
            self.canvas_widget.axes.scatter(self.config.ys_piont[:, 0], self.config.ys_piont[:, 1], c='blue', s=10, label='测量点')
        
        if self.config.check_point is not None:
            self.canvas_widget.axes.scatter(self.config.check_point[:, 0], self.config.check_point[:, 1], c='green', s=10, label='检查线')
        
        # 绘制重合点
        if self.coincident_points is not None and len(self.coincident_points) > 0:
            self.canvas_widget.axes.scatter(self.coincident_points[:, 0], self.coincident_points[:, 1], 
                                           c='red', s=30, marker='*', label='重合点')
        
        # 添加标签和图例
        self.canvas_widget.axes.set_xlabel('E坐标')
        self.canvas_widget.axes.set_ylabel('N坐标')
        self.canvas_widget.axes.set_title('测量点与检查线重合点分布图')
        self.canvas_widget.axes.legend()
        self.canvas_widget.axes.grid(True)
        
        # 调整坐标轴比例
        self.canvas_widget.axes.set_aspect('equal')
        
        # 刷新图形
        self.canvas_widget.draw()

# 如果作为主程序运行
if __name__ == '__main__':
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    window = CompareUI()
    window.show()
    sys.exit(app.exec_())
